const fs = require("fs");
const pluginName = "OutputI18nFilePlugin";
var langList = ["en-us", "zh-cn"];

function outputI18nFilePlugin(options = []) {
  langList = [...langList, ...options];
}

function outSwitch(state, cb) {
  if (!state) {
    return;
  }
  cb(state);
  switch (state.type) {
    case "ExpressionStatement":
      outSwitch(state.expression, cb);
      break;
    case "AssignmentExpression":
      outSwitch(state.left, cb);
      outSwitch(state.right, cb);
      break;
    case "BinaryExpression":
      outSwitch(state.left, cb);
      outSwitch(state.right, cb);
      break;
    case "BlockStatement":
      state.body.forEach(e => {
        outSwitch(e, cb);
      });
      break;
    case "FunctionExpression":
      outSwitch(state.id, cb);
      outSwitch(state.body, cb);
      break;
    case "VariableDeclaration":
      state.declarations.forEach(e => {
        outSwitch(e.id, cb);
        outSwitch(e.init, cb);
      });
      break;
    case "ReturnStatement":
      outSwitch(state.argument, cb);
      break;
    case "CallExpression":
      outSwitch(state.callee, cb);
      state.arguments.forEach(e => {
        outSwitch(e, cb);
      });
      /*
            if ( state.callee.property && state.callee.property.name === 'e$' ) {
                appendText ( state.arguments );
            }
            */
      break;
    case "Identifier":
      // end;
      // console.log( state.name );
      break;
    case "ObjectExpression":
      state.properties.forEach(e => {
        outSwitch(e, cb);
      });
      break;
    case "ArrayExpression":
      state.elements.forEach(e => {
        outSwitch(e, cb);
      });
      break;
    case "IfStatement":
      outSwitch(state.test, cb);
      outSwitch(state.consequent, cb);
      break;
    case "ForStatement":
      outSwitch(state.init, cb);
      outSwitch(state.test, cb);
      outSwitch(state.update, cb);
      outSwitch(state.body, cb);
      break;
    case "MemberExpression":
      outSwitch(state.object, cb);
      outSwitch(state.property, cb);
      break;
    case "Literal":
      // end;
      // console.log( state.value );
      break;
    case "UpdateExpression":
      outSwitch(state.argument, cb);
      break;
    case "Property":
      outSwitch(state.key, cb);
      outSwitch(state.value, cb);
      break;
  }
}

const textList = {};

function appendText(args) {
  textList[args[0].value] = {
    text: ""
  };
}

outputI18nFilePlugin.prototype.apply = compiler => {
  compiler.hooks.normalModuleFactory.tap(pluginName, factory => {
    factory.hooks.parser.for("javascript/auto").tap(pluginName, parser => {
      /*
            parser.hooks.statement.tap('OutputI18nFilePlugin', (state, opt) => {
                const mod = parser.state.module;
                if ( mod.resource && mod.resource.indexOf( 'foo.vue' ) !== -1 ) {
                    // 获取到js代码里的e$
                    // outExpression( state );
                }
            } );
            */
      parser.hooks.statement.tap(pluginName, state => {
        const mod = parser.state.module;
        outSwitch(state, st => {
          if (
            st.type === "CallExpression" &&
            st.callee.property &&
            st.callee.property.name === "e$"
          ) {
            textList[st.arguments[0].value] = {
              text: "",
              module: mod.resource,
              position: st.loc.start
            };
            //appendText ( state.arguments );
          }
        });
      });
    });

    /*
        compiler.hooks.make.tap( 'OutputI18nFilePlugin', compilation => {
            compilation.hooks.buildModule.tap( 'OutputI18nFilePlugin', mod => {
                console.log( mod.type );
            } )
        } )
        */

    /*
        compiler.hooks.compilation.tap( 'OutputI18nFilePlugin', compilation => {
        } )
        */
  });

  compiler.hooks.done.tap(pluginName, () => {
    // 开发时不生成语言文件包
    if (process.env.NODE_ENV !== "production") {
      return;
    }
    langList.forEach(lang => {
      fs.writeFileSync(
        `${__dirname}/../public/static/i18n/${lang}.json`,
        JSON.stringify(textList, " ", 4),
        {}
      );
    });
  });
};

module.exports = outputI18nFilePlugin;
